#include "tcpClient.hpp"
#include "sock.hpp"
#include "protocol.hpp"
#include "Util.hpp"
#include <iostream>
#include <string>

using namespace std;
using namespace protocol_ns;

static void usage(string proc){
    cout << "Usage:\n\t" << proc << "serverip serverport\n"
         << endl;
}

enum{
    LEFT,
    RIGHT
};

Request ParseLine(const string& line){
    string left, right;
    char op;
    int status = LEFT;
    for (auto &c : line){
        //这里当访问到运算符的时候status=OPER，但此时c仍然会++，再次循环的时候虽然status=OPER，但实际上已经指向RIGHT了
        // switch(status){
        //     case LEFT:
        //         if('0'<=c && c<='9'){
        //             left += c;
        //         }else{
        //             status = OPER;
        //         }
        //     case OPER:
        //         op = c;
        //         status = RIGHT;
        //     case RIGHT:
        //         if('0'<=c && c<='9'){
        //             right += c;
        //         }
        //         break;
        // }
        if(status == LEFT){
            if('0'<=c && c<='9'){
                left += c;
            }else{
                op = c;
                status = RIGHT;
            }
        }else{
            if('0'<=c && c<='9'){
                right += c;
            }
        }
    }
    Request req;
    req._x = Util::toInt(left);
    req._op = op;
    req._y = Util::toInt(right);
    return req;
}

int main(int argc, char* argv[]){

    if(argc!=3){
        usage(argv[0]);
        exit(USAGE_ERR);
    }
    string serverip = argv[1];
    uint16_t serverport = atoi(argv[2]);

    Sock sock;
    sock.Socket();
    int n = sock.Connect(serverip, serverport);
    if(n!=0){
        return -1;
    }

    string buf;

    while(1){


        //1、构建请求结构
        // Request req;
        // cout << "data1# ";
        // cin >> req._x;
        // cout << "op# ";
        // cin >> req._op;
        // cout << "data1# ";
        // cin >> req._y;
        // cout << "equation: " << req._x << req._op << req._y << endl;

        // //用户输入，格式：1+1、2*3
        cout << "Enter# ";
        string line;
        getline(cin, line);
        Request req = ParseLine(line);

        //2、请求结构序列化
        string send_str;
        req.Serialize(&send_str);

        //3、添加报头
        send_str = AddHeader(send_str);
        
        //4、向服务器发送
        send(sock.Fd(), send_str.c_str(), send_str.size(), 0);

        //5、获取相应
        string package;
        //从服务器读数据到buf，当检测到buf中存在一个完整的报文的时候，其提取出这个报文，放到package中
        READ:
        int n = ReadPackage(sock.Fd(), buf, &package);
        if (n == -1){
            break;
        }
        else if (n == 0){
            goto READ;
        }

        //6、提取有效载荷
        package = RemoveHeader(package, n);

        //7、反序列化
        Response res;
        res.DesSerialize(package);

        cout << "result# " << res._result << "  [code:" << res._code << "]" << endl;
    }

    sock.Close();

    return 0;
}